﻿using System.Collections.Generic;
using System.IO;
using Compass.Wasm.Shared.Extensions;
using Compass.Wasm.Shared.Purchases;
using Compass.Wpf.ApiServices.Purchases;
using Microsoft.Win32;
using OfficeOpenXml;

namespace Compass.Wpf.ViewModels.Purchases;

public class NavMonthlyConsRecvToolViewModel : NavigationViewModel
{
    #region ctor
    private readonly INavInvValuationService _navInvValuationService;
    private readonly INavInvReportClassService _navInvReportClassService;
    public NavMonthlyConsRecvToolViewModel(IContainerProvider provider) : base(provider)
    {
        _navInvValuationService = provider.Resolve<INavInvValuationService>();
        _navInvReportClassService = provider.Resolve<INavInvReportClassService>();

        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

        BrowseFileCommand = new DelegateCommand(BrowseFile);
        ReadInvReportClassCommand = new DelegateCommand(ReadInvReportClass);
        CalcTotalMTPTCommand = new DelegateCommand(CalcTotalMTPT);
        SaveTotalMTPTCommand = new DelegateCommand(SaveTotalMTPT);
        ExportExcelCommand = new DelegateCommand(ExportExcel);
        UpdateRoles = "admin,pur";
    }

    private string updateRoles;
    public string UpdateRoles
    {
        get => updateRoles;
        set { updateRoles = value; RaisePropertyChanged(); }
    }
    public DelegateCommand BrowseFileCommand { get; }
    public DelegateCommand ReadInvReportClassCommand { get; }
    public DelegateCommand CalcTotalMTPTCommand { get; }
    public DelegateCommand SaveTotalMTPTCommand { get; }
    public DelegateCommand ExportExcelCommand { get; }
    #endregion

    #region 属性
    private bool isEnable = true;
    public bool IsEnable
    {
        get => isEnable;
        set { isEnable = value; RaisePropertyChanged(); }
    }

    private string invReportClassPath;
    public string InvReportClassPath
    {
        get => invReportClassPath;
        set { invReportClassPath = value; RaisePropertyChanged(); }
    }

    private string textMTPT = "(请先计算MTPT)";
    public string TextMTPT
    {
        get => textMTPT;
        set { textMTPT = value; RaisePropertyChanged(); }
    }
    private int totalMTPT;
    public int TotalMTPT
    {
        get => totalMTPT;
        set { totalMTPT = value; RaisePropertyChanged(); }
    }
    private string search;
    /// <summary>
    /// 搜索条件属性
    /// </summary>
    public string Search
    {
        get => search;
        set
        {
            search = value;
            RaisePropertyChanged();
            Filter();
        }
    }
    public ObservableRangeCollection<NavMonthlyValuationDto> FSMonthlyValuationDtos { get; } = new();
    public ObservableRangeCollection<NavMonthlyValuationDto> FilterFSMonthlyValuationDtos { get; } = new();
    #endregion

    #region 浏览文件
    private void BrowseFile()
    {
        var dialog = new OpenFileDialog
        {
            Filter = "Excel|*.xlsx",
            InitialDirectory = Environment.GetFolderPath(System.Environment.SpecialFolder.DesktopDirectory)
        };

        if (dialog.ShowDialog() != true) return;
        InvReportClassPath=dialog.FileName;
    }
    #endregion

    #region 初始化NavInvReportClass时使用
    private async void ReadInvReportClass()
    {
        IsEnable = false;
        await Task.Delay(100);
        if (string.IsNullOrEmpty(InvReportClassPath))
        {
            Aggregator.SendMessage("请选择InvReportClass表格地址！");
            IsEnable = true;
            return;
        }

        ChangeInvReportClassTitle(InvReportClassPath);

        var invReportClassStrings = InvReportClassPath.ReadFromExcel<List<NavInvReportClassString>>();

        var invReportClassDtos = invReportClassStrings.Select(x =>
            new NavInvReportClassDto
            {
                //获取到当月最后一天
                YearMonth = x.YearMonth.ToDateTime().AddDays(1 - x.YearMonth.ToDateTime().Day).AddMonths(1).AddDays(-1),
                RawMtlValue = x.RawMtlValue.ToDouble(),
                SemiProdValue = x.SemiProdValue.ToDouble(),
                FgTradeValue = x.FgTradeValue.ToDouble(),
                FsSubtotal = x.FsSubTotal.ToDouble(),
                MTPT = x.MTPT.ToInt(),
                RecvValue = x.RecvValue.ToDouble(),
                ConsValue = x.ConsValue.ToDouble(),
                Gap = x.Gap.ToDouble()
            });

        foreach (var item in invReportClassDtos)
        {
            var exist = await _navInvReportClassService.GetSingleByMonthAsync(item.YearMonth);
            if (exist.Status)
            {
                await _navInvReportClassService.UpdateAsync(exist.Result.Id.Value, item);
            }
            else
            {
                await _navInvReportClassService.AddAsync(item);
            }
        }

        Aggregator.SendMessage("已读取NavInvReportClass并保存表格信息！");
        IsEnable = true;
    }

    private void ChangeInvReportClassTitle(string path)
    {
        using var package = new ExcelPackage(path);

        //修改表头,方便后面读取数据
        //Epplus的所有行列数都是以1开始的
        var worksheet = package.Workbook.Worksheets[0];//第一张表格
        //直接指定单元格进行赋值
        worksheet.Cells["A1"].Value = "YearMonth";
        worksheet.Cells["B1"].Value = "RawMtlValue";
        worksheet.Cells["C1"].Value = "SemiProdValue";
        worksheet.Cells["D1"].Value = "FgTradeValue";
        worksheet.Cells["E1"].Value = "FsSubTotal";
        worksheet.Cells["F1"].Value = "MTPT";
        worksheet.Cells["G1"].Value = "RecvValue";
        worksheet.Cells["H1"].Value = "ConsValue";
        worksheet.Cells["I1"].Value = "Gap";

        // 保存Excel文件
        package.Save();
    }

    #endregion

    #region 计算和保存TotalMTPT库存周转天数
    private void CalcTotalMTPT()
    {
        //库存周转天数=30/库存周转率=（30*平均存货余额）/销货成本

        //我们的计算规则：库存周转天数=30/库存周转率=（30*当月存货余额）/12平均销货成本
        var totalInvValue = Math.Round(FSMonthlyValuationDtos.Sum(x => x.InvValue), 2);
        var totalConsValue = Math.Round(FSMonthlyValuationDtos.Sum(x => x.ConsAvg12Value), 2);
        TotalMTPT = (int)Math.Ceiling(30d * totalInvValue / totalConsValue);
        TextMTPT = $"MTPT = 30 X {totalInvValue} / {totalConsValue} = {TotalMTPT}";
    }

    private async void SaveTotalMTPT()
    {
        if (TotalMTPT == 0)
        {
            Aggregator.SendMessage("请先计算MTPT");
            return;
        }
        //提示信息，保存确认，月份
        var lastMonth = DateTime.Today.AddDays(1 - DateTime.Today.Day).AddDays(-1);
        //保存询问
        var dialogResult = await DialogHost.Question("保存确认", $"确认要保存{lastMonth.Year}年{lastMonth.Month}月的MTPT数据吗?");
        if (dialogResult.Result != ButtonResult.OK)
        {
            IsEnable = true;
            return;
        }
        //todo:保存库存类别汇总数据NavInvReportClass的MTPT
        var existReport = await _navInvReportClassService.GetSingleByMonthAsync(lastMonth);
        if (existReport.Status)
        {
            var dto = existReport.Result;
            dto.MTPT = TotalMTPT;//此处只修改MTPT
            await _navInvReportClassService.UpdateAsync(dto.Id.Value, dto);
            Aggregator.SendMessage($"已更新{lastMonth.Year}年{lastMonth.Month}月的MTPT");
        }
        else
        {
            Aggregator.SendMessage("请先更新上个月的InvValuation库存估值后再保存MTPT");
        }
    }
    #endregion

    #region 导出Excel
    private void ExportExcel()
    {
        IsEnable = false;
        var tableName = "MonthlyValuation";
        var tablePath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.DesktopDirectory), $"【Compass】{tableName}{DateTime.Now:yyyy-MM-dd-hh-mm-ss}.xlsx");

        if (FSMonthlyValuationDtos.Any())
        {
            var monthlyValuationNoEnums = FSMonthlyValuationDtos.Select(x =>
                new NavMonthlyValuationNoEnum()
                {
                    Number = x.Number,
                    Start = x.Start,
                    Sbu = x.Sbu.ToString(),
                    Description = x.Description,
                    Unit = x.Unit.ToString(),

                    UnitCost = x.UnitCost,
                    Inventory = x.Inventory,
                    InvValue=x.InvValue,
                    SafetyStock = x.SafetyStock,
                    SsValue=x.SsValue,
                    OpenPo = x.OpenPo,
                    OpenPoValue = x.OpenPoValue,
                    MTPT = x.MTPT,

                    ConsFrequency = x.ConsFrequency,
                    ConsAvg12 = x.ConsAvg12,
                    ConsAvg12Value = x.ConsAvg12Value,
                    ConsAvg6 = x.ConsAvg6,
                    ConsAvg3 = x.ConsAvg3,

                    RecvFrequency = x.RecvFrequency,
                    RecvAvg12 = x.RecvAvg12,
                    RecvAvg12Value = x.RecvAvg12Value,
                    RecvAvg6 = x.RecvAvg6,
                    RecvAvg3 = x.RecvAvg3,
                }
            );
            monthlyValuationNoEnums.WriteExcel(tablePath, tableName);

            Aggregator.SendMessage("导出MonthlyValuation数据Excel到桌面完成！");
        }
        else
        {
            Aggregator.SendMessage("没有数据，不能导出Excel！");
        }
        IsEnable = true;
    }
    #endregion

    #region 筛选
    private void Filter()
    {
        FilterFSMonthlyValuationDtos.ReplaceRange(
            FSMonthlyValuationDtos.Where(x =>
                string.IsNullOrEmpty(Search)||
                 x.Number.Contains(Search, StringComparison.OrdinalIgnoreCase)||
                 (!string.IsNullOrEmpty(x.Description)&&x.Description!.Contains(Search, StringComparison.OrdinalIgnoreCase))
            ));
        //有的时候Remarks是null，导致调用Contains报错
    }
    #endregion

    #region 导航和初始化
    private void GetEnumNames()
    {
        //初始化一些枚举值
        //Units=Enum.GetNames(typeof(Unit_e));
        //Sbus=Enum.GetNames(typeof(Sbu_e));
        //Groups=Enum.GetNames(typeof(Group_e));
    }

    private async void GetDataAsync()
    {
        IsEnable = false;
        var response = await _navInvValuationService.GetMonthlyValuationsAsync();
        if (response.Status)
        {
            FSMonthlyValuationDtos.ReplaceRange(response.Result);
        }
        else
        {
            FSMonthlyValuationDtos.Clear();
        }
        Filter();
        IsEnable = true;
    }

    public override void OnNavigatedTo(NavigationContext navigationContext)
    {
        base.OnNavigatedTo(navigationContext);
        GetEnumNames();
        GetDataAsync();
    }
    #endregion
}